import logging
import os
import sys
import unittest

import search
import util


__author__  = 'ZL <837806295@qq.com>'
__product__ = 'test'
__version__ = '3.2.0'
__date__    = '2023/04/08'


log = logging.getLogger(__product__)


class TestCase001(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.test_sequence = 0
        cls.work_dir = util.get_test_subdir(__file__, cls.__name__)

    @classmethod
    def tearDownClass(cls):
        del cls.test_sequence
        del cls.work_dir

        util.remove_test_subdir(__file__, cls.__name__)

    def setUp(self):
        self.test_sequence = self.__class__.test_sequence
        self.work_dir = self.__class__.work_dir
        self.test_dir = util.get_subdir(
            self.work_dir,
            ('{:0>%d}' % 3).format(self.test_sequence + 1))

    def tearDown(self):
        del self.test_sequence
        del self.work_dir
        del self.test_dir

        self.__class__.test_sequence += 1

    def test_command(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" -h'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py')
                )
        )

        self.assertTrue(util.run(cmd))

class TestCase002(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.test_sequence = 0
        cls.work_dir = util.get_test_subdir(__file__, cls.__name__)

    @classmethod
    def tearDownClass(cls):
        del cls.test_sequence
        del cls.work_dir

        util.remove_test_subdir(__file__, cls.__name__)

    def setUp(self):
        self.test_sequence = self.__class__.test_sequence
        self.work_dir = self.__class__.work_dir
        self.test_dir = util.get_subdir(
            self.work_dir,
            ('{:0>%d}' % 3).format(self.test_sequence + 1))

    def tearDown(self):
        del self.test_sequence
        del self.work_dir
        del self.test_dir

        self.__class__.test_sequence += 1

    def test_subcommand_search(self):
        if not sys.executable:
            return

        cmd = (
            '"%s" "%s" search -h'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py')
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_search2(self):
        if not sys.executable:
            return

        keywords = ('False await else import pass None break except in raise '
                    'True class finally is return and continue for lambda try '
                    'as def from nonlocal while assert del global not with '
                    'async elif if or yield')

        cmd = (
            '"%s" "%s" search "%s" %s'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data']),
                        'compare.py'),
                    keywords
                )
        )

        self.assertTrue(util.run(cmd))

    def test_subcommand_search3(self):
        if not sys.executable:
            return

        keywords = ('False await else import pass None break except in raise '
                    'True class finally is return and continue for lambda try '
                    'as def from nonlocal while assert del global not with '
                    'async elif if or yield')

        cmd = (
            '"%s" "%s" search -m 1 "%s" %s'
                % (
                    sys.executable,
                    os.path.join(util.get_launch_dir(__file__), 'main.py'),
                    os.path.join(
                        util.get_test_subdir(__file__, ['data']),
                        'compare.py'),
                    keywords
                )
        )

        self.assertTrue(util.run(cmd))

class TestCase101(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.test_sequence = 0
        cls.work_dir = util.get_test_subdir(__file__, cls.__name__)

    @classmethod
    def tearDownClass(cls):
        del cls.test_sequence
        del cls.work_dir

        util.remove_test_subdir(__file__, cls.__name__)

    def setUp(self):
        self.test_sequence = self.__class__.test_sequence
        self.work_dir = self.__class__.work_dir
        self.test_dir = util.get_subdir(
            self.work_dir,
            ('{:0>%d}' % 3).format(self.test_sequence + 1))

    def tearDown(self):
        del self.test_sequence
        del self.work_dir
        del self.test_dir

        self.__class__.test_sequence += 1

class TestCase102(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.test_sequence = 0
        cls.work_dir = util.get_test_subdir(__file__, cls.__name__)

    @classmethod
    def tearDownClass(cls):
        del cls.test_sequence
        del cls.work_dir

        util.remove_test_subdir(__file__, cls.__name__)

    def setUp(self):
        self.test_sequence = self.__class__.test_sequence
        self.work_dir = self.__class__.work_dir
        self.test_dir = util.get_subdir(
            self.work_dir,
            ('{:0>%d}' % 3).format(self.test_sequence + 1))

    def tearDown(self):
        del self.test_sequence
        del self.work_dir
        del self.test_dir

        self.__class__.test_sequence += 1

    def test_nfa(self):
        text = 'abcdef xyabc defxyd adfl abc dxf'

        nfa = search.build_nfa_from_keys(['abc', 'def'])
        search.run_nfa_for_searching(nfa, text[0:16])
        search.run_nfa_for_searching(nfa, text[16:32])

        self.assertFalse({3, 12, 28} ^ search.get_nfa_statistics(nfa)['abc'])
        self.assertFalse({6, 16} ^ search.get_nfa_statistics(nfa)['def'])

    def test_nfa2(self):
        text = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'

        nfa = search.build_nfa_from_keys(['a', 'aa'])
        search.run_nfa_for_searching(nfa, text[0:16])
        search.run_nfa_for_searching(nfa, text[16:32])

        self.assertFalse(
            {i for i in range(1, 33)} ^ search.get_nfa_statistics(nfa)['a'])
        self.assertFalse(
            {i for i in range(2, 33)} ^ search.get_nfa_statistics(nfa)['aa'])

    def test_nfa3(self):
        text = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'

        nfa = search.build_nfa_from_keys(['a', 'aa'])
        search.run_nfa_for_searching(nfa, text[0:16])
        search.run_nfa_for_searching(nfa, text[16:32])

        search.reset_nfa(nfa)
        search.run_nfa_for_searching(nfa, text[0:16])
        search.run_nfa_for_searching(nfa, text[16:32])

        self.assertFalse(
            {i for i in range(1, 33)} ^ search.get_nfa_statistics(nfa)['a'])
        self.assertFalse(
            {i for i in range(2, 33)} ^ search.get_nfa_statistics(nfa)['aa'])


if __name__ == '__main__':
    util.set_log(__file__, '%s_v%s' % (__product__, __version__), 'debug')

    log.info('program version: %s %s', __product__, __version__)
    log.debug('command line: %s', sys.argv)

    unittest.main()
